﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;

namespace 透明度设置工具
{
	public partial class MainForm : Form
	{
		private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);

		//用来遍历所有窗口 
		[DllImport("user32.dll")]
		private static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);

		//获取窗口Text 
		[DllImport("user32.dll")]
		private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);

		[DllImport("user32.dll")]
		private static extern uint GetWindowLongA(IntPtr hWnd, int nIndex);

		[DllImport("user32.dll")]
		private static extern uint SetWindowLongA(IntPtr hWnd, int nIndex,uint dwNewLong);

		[DllImport("user32.dll")]
		private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey,byte bAlpha, uint dwFlags);

		[DllImport("Kernel32.dll")]
		private static extern uint GetLastError();
		const int GWL_STYLE = -16;
		const int GWL_EXSTYLE = -20;
		const uint WS_VISIBLE = 0x10000000;
		const uint LWA_ALPHA = 0x00000002;
		const uint WS_EX_LAYERED = 0x00080000;


		public class WindowInfo
		{
			public IntPtr hWnd { get; set; }
			public string szWindowName { get; set; }
		}

		public List<WindowInfo> GetAllDesktopWindows()
		{
			//用来保存窗口对象 列表
			List<WindowInfo> wndList = new List<WindowInfo>();

			//enum all desktop windows 
			EnumWindows(delegate (IntPtr hWnd, int lParam)
			{
				WindowInfo wnd = new WindowInfo();
				StringBuilder sb = new StringBuilder(1024);

				//get hwnd 
				wnd.hWnd = hWnd;

				//get window name  
				GetWindowTextW(hWnd, sb, sb.Capacity);
				wnd.szWindowName = sb.ToString();

				//add it into list 
				if (wnd.szWindowName.Length != 0) 
					if((GetWindowLongA(wnd.hWnd,GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE)
						wndList.Add(wnd);
				return true;
			}, 0);

			return wndList;
		}

		List<WindowInfo> WindowList;

		public MainForm()
		{
			InitializeComponent();
			UpdateWindowList();
		}

		void UpdateWindowList()
		{
			WindowList = GetAllDesktopWindows();
			WindowList.Sort((x,y)=>x.szWindowName.CompareTo(y.szWindowName));
			list_Window.DataSource = WindowList;
			list_Window.DisplayMember = "szWindowName";
		}

		const int tbarHeight = 45;
		const int boundWidth = 10;
		const int btnHeight = 22;
		const int btnWidth = 58;

		void MainForm_Resize()
		{
			list_Window.SetBounds(boundWidth, boundWidth,
				ClientRectangle.Width - 2 * boundWidth, ClientRectangle.Height - tbarHeight - 2 * boundWidth);

			tbar_trans.SetBounds(boundWidth, 2 * boundWidth + list_Window.Height,
				ClientRectangle.Width - 5 * boundWidth - 3 * btnWidth, tbarHeight);

			tbox_trans.SetBounds(2 * boundWidth + tbar_trans.Width, 2 * boundWidth + list_Window.Height + (tbarHeight - btnHeight) / 2
				, btnWidth, btnHeight);

			btn_refresh.SetBounds(3 * boundWidth + tbar_trans.Width + 1 * btnWidth, 2 * boundWidth + list_Window.Height + (tbarHeight - btnHeight) / 2
				, btnWidth, btnHeight);

			btn_set.SetBounds(4 * boundWidth + tbar_trans.Width + 2 * btnWidth, 2 * boundWidth + list_Window.Height + (tbarHeight - btnHeight) / 2
				, btnWidth, btnHeight);

		}

		private void MainForm_Load(object sender, EventArgs e)
		{
			MainForm_Resize();
		}

		private void MainForm_SizeChanged(object sender, EventArgs e)
		{
			MainForm_Resize();
		}

		private void tbox_trans_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
			{
				e.Handled = true;
				return;
			}
		}

		private void tbar_trans_Scroll(object sender, EventArgs e)
		{
			tbox_trans.Text = tbar_trans.Value.ToString();
		}

		private void tbox_trans_TextChanged(object sender, EventArgs e)
		{

			if (tbox_trans.Text.Length != 0)
			{
				var tbxValue = int.Parse(tbox_trans.Text);
				if (tbxValue <= 255)
					tbar_trans.Value = tbxValue;
				else
					tbox_trans.Text = "255";
			}
			else
				tbox_trans.Text = "0";
		}

		private void btn_refresh_Click(object sender, EventArgs e)
		{
			UpdateWindowList();
		}

		private void btn_set_Click(object sender, EventArgs e)
		{
			var hwnd = (list_Window.SelectedItem as WindowInfo).hWnd;
			var trans = (byte)tbar_trans.Value;
			var winLong = GetWindowLongA(hwnd, GWL_EXSTYLE);
			winLong |= WS_EX_LAYERED;
			SetWindowLongA(hwnd, GWL_EXSTYLE, winLong);
			SetLayeredWindowAttributes(hwnd, 0x00FFFFFF, trans, LWA_ALPHA);
			var error = GetLastError();
		}
	}
}
